import 'dart:math';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
//主页
class IndexPage extends StatefulWidget {
  @override
  _IndexPageState createState() => _IndexPageState();
}
class _IndexPageState extends State<IndexPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("demo"),
      ),
      body: _buildBodyView(),
    );
  }
  _buildBodyView(){
    return Container(
      // color: Colors.red,
      margin: EdgeInsets.only(top: 50),
      alignment: Alignment.center,
      child: _MyChartView(),
    );
  }

}
//自定义图标
class _MyChartView extends StatefulWidget{
  @override
  __MyChartViewState createState() => __MyChartViewState();
}

class __MyChartViewState extends State<_MyChartView> {
  final _tag = "_MyChartView";
  List<double> values =  List.generate(100, (int index) => (30+Random().nextDouble()*50).toDouble());
  double value = 1;//
  bool isDotShow = true;
  int selectIndex = 0;//

  //paint 参数
  double chartWidth = 0, chartHeight = 0;
  double offsetX = .0;//横轴坐标间隔

  @override
  void initState() {
    selectIndex = values.length - 1;//默认最后一个值
    value = values[selectIndex];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    chartWidth = MediaQuery.of(context).size.width;
    chartHeight = 300;
    offsetX = (chartWidth-24)/(values.length - 1);
    return Column(
      children: [
        Text("${value.toStringAsFixed(1)} ￥"),
        GestureDetector(
          onPanStart: _onPanStart,
          onPanUpdate: _onPanUpdate,
          onPanEnd: _onPanEnd,
          child: CustomPaint(
            size: Size(chartWidth, chartWidth),
            painter: _MyPainter(values: values, isDotShow: isDotShow, offsetX: offsetX, selectIndex: selectIndex)
          ),
        ),
      ],
    );
  }

  _onPanStart(DragStartDetails e){
    print("$_tag _onPanStart $isDotShow");
    // isDotShow = true;
    calValueIndexFromPoint(e.globalPosition.dx);
    setState(() {

    });
  }

  _onPanUpdate(DragUpdateDetails e) {
    print("$_tag _onPanUpdate $isDotShow");
    calValueIndexFromPoint(e.globalPosition.dx);
    setState(() {

    });
  }

  _onPanEnd(DragEndDetails e) {
    print("$_tag _onPanEnd $isDotShow");
    // isDotShow = false;
    setState(() {

    });
  }

  void calValueIndexFromPoint(double x){
    x = x-12;
    for(int i=0; i < values.length; i++ ){
      if(x>=(i*offsetX) && x<=(i*offsetX+offsetX/2)){
        selectIndex = i;
        break;
      }
    }
    value = values[selectIndex];
    print("$_tag calValueIndexFromPoint x $x,  selectIndex $selectIndex");
  }

}
class _MyPainter extends CustomPainter{
  final List<double> values;
  bool isDotShow = false;
  int selectIndex;
  double offsetX, offsetY;


  _MyPainter({this.values, this.isDotShow, this.offsetX, this.selectIndex}); //数值-单元格对比

  @override
  void paint(Canvas canvas, Size size) {
    print("paint size $size");
    _drawLines(canvas, size);
    _drawDot(canvas, size);
  }

  //绘制折线图
  _drawLines(Canvas canvas, Size size){
    double offsetX = (size.width-24)/(values.length-1);
    var _path = Path();
    for(int i=0;i< values.length; i++){
      double x = i*offsetX+12;
      double y = values[i];
      i==0?_path.moveTo(x, y):_path.lineTo(x, y);
      // print("point ${x}, ${y}");
    }
    // _path.close();

    if(true){//渐变
      var _pathRect = Path();
      double maxY = values[0];
      for(int i=0;i< values.length; i++){
        double x = i*offsetX+12;
        double y = values[i];
        i==0?_pathRect.moveTo(x, y):_pathRect.lineTo(x, y);
        if(y>maxY){
          maxY = y;
        }
      }
      _pathRect.lineTo((values.length-1)*offsetX+12, maxY+40);
      _pathRect.lineTo(12, maxY+40);
      _pathRect.close();

      // canvas.drawPath(_pathRect, Paint()..color=Colors.red..style=PaintingStyle.fill);
      canvas.save();
      canvas.clipPath(_pathRect);
      final paint = Paint()
        ..shader = LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Colors.blue.withOpacity(.1),
            Colors.white,
          ],
          // stops: [0.4, 0.4]
        ).createShader(Rect.fromLTWH(0, 0, 0, 80));
      canvas.drawPath(_pathRect, paint);
      canvas.restore();
    }


    canvas.drawPath(_path, Paint()..strokeWidth=2..color=Colors.blue..style=PaintingStyle.stroke);
  }

  //绘制圆点-手指移动显示
  _drawDot(Canvas canvas, Size size){
    print("_MyPainter _drawDot $isDotShow");
    if(isDotShow){
      double x = selectIndex*offsetX +12;
      double y = values[selectIndex];
      print("_MyPainter _drawDot $isDotShow x $x, y $y");
      Offset center = Offset(x, y);
      Path oval = Path()..addOval(Rect.fromCircle(center: center, radius: 10));
      canvas.drawShadow(oval, Colors.black54, 2, true);
      canvas.drawCircle(center, 10, Paint()..color=Colors.white..style=PaintingStyle.fill);
      canvas.drawCircle(center, 5, Paint()..color=Colors.blueAccent..style=PaintingStyle.fill);
    }
  }

  @override
  bool shouldRepaint(_MyPainter oldDelegate) {
    if(oldDelegate.selectIndex!=this.selectIndex || !isDotShow){//避免重绘
      return true;
    }else{
      return false;
    }
  }
}